package framework.spatial;

import java.awt.Graphics;
import java.awt.Point;

/**
 *
 * @author Lukáš Marek
 */
public class FRDSpatialGCircle extends FRDSpatialGItem
{
	private Point p1,p2;
	
	public FRDSpatialGCircle()
	{
		p1 = new Point();
		p2 = new Point();
	}

	public void setLocation(Point p1, Point p2)
	{
		this.p1.setLocation(p1);
		this.p2.setLocation(p2);
	}
	
	public Point[] getLocation()
	{
		Point ret[] = new Point[2];
		ret[0] = p1;
		ret[1] = p2;
		return ret;
	}
	
	@Override
	public void setPoints(Point p1, Point p2)
	{
		this.p1.setLocation(mapPoint(p1));
		this.p2.setLocation(mapPoint(p2));
	}
	
	@Override
	public boolean addPoints(Point p1, Point p2)
	{
		if (p1.distance(p2) < 5)
			return false;
		else
		{
			this.p1.setLocation(mapPoint(p1));
			this.p2.setLocation(mapPoint(p2));
			return true;
		}
	}

	@Override
	public void draw(Graphics g)
	{
		if (selected)
			g.setColor(SelectedColor);
		else
			g.setColor(defaultColor);
		int size = (int) p1.distance(p2);
		Point p = showPoint(new Point(p1.x - size, p1.y - size));
		size = showSize(2 * size);
		g.fillArc(p.x, p.y, size, size, 360, 360);
	}	

	@Override
	public void drawEdit(Graphics g, Point pt1, Point pt2)
	{
		g.setColor(editColor);
		int size = (int) p1.distance(p2);
		if ((p1.distance(mapPoint(pt1)) <= size + 20) && (p1.distance(mapPoint(pt1)) >= size - 20))
		{
			int nsize = (int) p1.distance(mapPoint(pt2));
			Point p = showPoint(new Point(p1.x - nsize, p1.y - nsize));
			nsize = showSize(2 * nsize);
			g.fillArc(p.x, p.y, nsize, nsize, 360, 360);
		}
		else if (undermouse(pt1))
		{
			Point p = showPoint(new Point(p1.x - size, p1.y - size));
			size = showSize(2 * size);
			g.fillArc(p.x + (pt2.x - pt1.x), p.y + (pt2.y - pt1.y), size, size, 360, 360);
		}
	}
	
	@Override
	public void saveEdit(Point pt1, Point pt2)
	{
		int size = (int) p1.distance(p2);
		if ((p1.distance(mapPoint(pt1)) <= size + 20) && (p1.distance(mapPoint(pt1)) >= size - 20))
		{
			p2.setLocation(mapPoint(pt2));
		}
		else if (undermouse(pt1))
		{
			Point mp1 = mapPoint(pt1);
			Point mp2 = mapPoint(pt2);
			p1.x += mp2.x - mp1.x;
			p1.y += mp2.y - mp1.y;
			p2.x += mp2.x - mp1.x;
			p2.y += mp2.y - mp1.y;
		}
	}

	@Override
	public boolean undermouse(Point _p)
	{
		int rz = (selected) ? (int)(10/back.getScale()*back.getZoom()) : 0;
		int size = Math.max(Math.abs(p2.x - p1.x), Math.abs(p2.y - p1.y));
		return (p1.distance(mapPoint(_p)) <= size + rz);
	}
	
	/**
	 * prepocita bod z mapy na bod v panelu
	 * @param pt bod
	 * @return 
	 */
	private Point showPoint(Point pt)
	{
		double scale = back.getScale();
		Point zoomLoc = back.getPosition();
		double zoom = back.getZoom();
		double df = scale / zoom;
		Point ret = new Point();
		ret.x = (int)((pt.x - zoomLoc.x) / df);
		ret.y = (int)((pt.y - zoomLoc.y) / df);
		return ret;
	}
	
	/**
	 * prepocita velikost z mapy na velikost v panelu
	 * @param pt
	 * @return 
	 */
	private int showSize(int pt)
	{
		double scale = back.getScale();
		double zoom = back.getZoom();
		double df = scale / zoom;
		int ret = (int)(pt / df);
		return ret;
	}
	
	/**
	 * prepocita bod z panelu na bod v mape
	 * @param pt
	 * @return 
	 */
	private Point mapPoint(Point pt)
	{
		double scale = back.getScale();
		Point zoomLoc = back.getPosition();
		double zoom = back.getZoom();
		double df = scale / zoom;
		Point ret = new Point();
		ret.x = (int)(pt.x * df) + zoomLoc.x;
		ret.y = (int)(pt.y * df) + zoomLoc.y;
		return ret;
	}
}
